#ifndef WIIMOTESTATUSDIALOG_H
#define WIIMOTESTATUSDIALOG_H

#ifdef WIIMOTE

#include <QDialog>
#include <QLabel>
#include <QMap>

#include "qwiimote.h"

namespace Ui {
    class WiimoteStatusDialog;
}

/**
  * @brief Enables Wiimote support in the GUI while also providing a way to restrict input to a certain function at
  * a time. This owns the qWiimote object used to talk to and from the Wiimote, and manages what widget currently
  * 'owns' the input from the Wiimote.
  *
  * This 'ownership' is referred to as association in this little system, and works like this. The root window
  * self associates itself with this dialog by calling it's personally setWiimote() function. From then on,
  * whenever a widget wishes to pass ownership on to another, it should call WiimoteStatusDialog::associate()
  * with the new widget as the argument, and then after the new widget is done, it should call
  * WiimoteStatusDialog::associate() again but this time with the return value from the first call as its
  * parameter. Perhaps at some point I'll implement this as an internal stack, but for now this works.
  */
class WiimoteStatusDialog : public QDialog {
private:
    Q_OBJECT
    Ui::WiimoteStatusDialog *ui;
    int oldX;
    int oldY;
//protected:
    qWiimote* _wiimote;
    QMap<qWiimote::Button, QLabel*> _labels;
    QMap<qWiimote::Button, const char *> _signals;
    QMap<qWiimote::Button, QPair<const QObject*, const char*> > _activeConnections;
    QVector<QPair<const QObject*, const char*> > _positiveFeedback;
    QVector<QPair<const QObject*, const char*> > _negativeFeedback;
public:
    explicit WiimoteStatusDialog(qWiimote* _wiimote, QWidget *parent = 0);
    ~WiimoteStatusDialog();

    /**
      * @brief Associates the WiimoteStatusDialog with a particular WiimoteWidget. If dialog isn't a WiimoteWidget,
      * it doesn't have anything to associate.
      *
      * @param dialog
      */
    QWidget* associate(QWidget* dialog);

    /**
      * @brief Gets the wiimote associated with this dialog.
      */
    qWiimote* getWiimote();
public slots:
    /**
      * @brief Associates a button on the wiimote with a slot, and gives it a string to display to the user
      * to show what action it will be.
      *
      * @param button
      * @param command
      * @param receiver
      * @param member
      */
    void setCommand(qWiimote::Button button, QString command, const QObject * receiver, const char * member);
    /**
      * @brief Links a signal to send positive feedback back to the wiimote. Should not pass arguments.
      *
      * @param sender
      * @param signal
      */
    void linkPositiveFeedback(const QObject* sender, const char* signal);
    /**
      * @brief Links a signal to send negative feedback to the wiimote. Should not pass arguments.
      *
      * @param sender
      * @param signal
      */
    void linkNegativeFeedback(const QObject* sender, const char* signal);
    /**
      * @brief Clears and removes all commands from the dialog. Also disconnects any signals associated with them.
      */
    void clearCommands();
private slots:
    /**
      * @brief Causes the controller to rumble whenever a user interaction is accepted.
      */
    void positiveFeedback();
    /**
      * @brief Causes the controller to rumble for longer when a user interaction failed.
      */
    void negativeFeedback();
    void updateBattery(float percent);

    // Can be used to record metadata about which buttons were pressed when
    void recordButton(qWiimote::Button button);
private:
    void showEvent(QShowEvent *event);
    void hideEvent(QHideEvent *event);
};

#endif // WIIMOTE

#endif // WIIMOTESTATUSDIALOG_H
